package com.woniu.aspect;

import cn.dev33.satoken.util.SaResult;
import com.woniu.entity.SysLoginLog;
import com.woniu.entity.dto.LoginDTO;
import com.woniu.entity.vo.AllUserVO;
import com.woniu.service.SysLoginLogService;
import com.woniu.utils.IpUtils;
import com.woniu.utils.UserAgentUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * @Author pml
 * @Date 2025/6/18 23:10
 * @Description TODO
 * 登录日志AOP切面
 * 环绕登录方法，记录登录日志
 */
@Aspect
@Component
public class LoginLogAspect {

    @Autowired
    private SysLoginLogService sysLoginLogService;

    /**
     * 定义切入点：匹配LoginController的login方法
     * 包含LoginDTO和ServerWebExchange两个参数
     */
    @Pointcut("execution(* com.woniu.controller.LoginController.login(..)) && args(loginDTO, exchange)")
    public void loginPointcut(LoginDTO loginDTO, ServerWebExchange exchange) {}

    /**
     * 环绕通知：在登录方法执行前后记录日志
     */
    @Around("loginPointcut(loginDTO, exchange)")
    public Object aroundLogin(ProceedingJoinPoint joinPoint, LoginDTO loginDTO, ServerWebExchange exchange) throws Throwable {
        // 从登录DTO中获取用户名（假设LoginDTO有getUserName方法）

        String userName = loginDTO.getUserName();

        // 获取客户端IP地址
        String ip = IpUtils.getIpAddress(exchange);

        // 解析User-Agent获取设备和浏览器信息
        String userAgent = exchange.getRequest().getHeaders().getFirst("User-Agent");
        Map<String, String> userAgentInfo = UserAgentUtils.parseUserAgent(userAgent);

        // 执行目标登录方法
        Object result = joinPoint.proceed();

        // 处理响应结果，记录日志
        if (result instanceof Mono) {
            return ((Mono<?>) result).flatMap(res -> {
                SysLoginLog loginLog = new SysLoginLog();
                loginLog.setLoginTime(LocalDateTime.now());
                loginLog.setLoginIp(ip);
                loginLog.setDeviceInfo(userAgentInfo.get("device"));
                loginLog.setBrowserInfo(userAgentInfo.get("browser"));
                loginLog.setLoginMethod("password"); // 当前登录方式为密码登录
                loginLog.setCreateTime(LocalDateTime.now());
                loginLog.setCreator("system");

                // 根据登录结果设置状态和备注
                if (res instanceof SaResult) {
                    SaResult saResult = (SaResult) res;
                    if (saResult.getCode() == 200) {
                        // 登录成功
                        AllUserVO userVO = (AllUserVO) saResult.getData();
                        loginLog.setLoginStatus(1);
                        loginLog.setUserId(userVO.getUserId()); // 直接使用AllUserVO的getter方法
                        loginLog.setRemark("用户" + userName + "登录成功");
                    } else {
                        // 登录失败
                        loginLog.setLoginStatus(0);
                        loginLog.setRemark("用户" + userName + "登录失败: " + saResult.getMsg());
                    }
                } else {
                    loginLog.setLoginStatus(0);
                    loginLog.setRemark("用户" + userName + "登录异常");
                }

                // 保存日志并返回原始结果
                return sysLoginLogService.saveLoginLog(loginLog)
                        .thenReturn(res);
            });
        }

        return result;
    }
}
